package com.xiaomaoguai.javassist.kepler.listener.convertor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xiaomaoguai.fcp.pre.kepler.convert.core.ConvertManager;
import com.xiaomaoguai.fcp.pre.kepler.convert.core.support.ConvertZkNode;
import com.xiaomaoguai.fcp.pre.kepler.zk.integration.listener.PathNodeDataConsumerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 格转配置监听
 *
 * @author huwenxuan
 * @date 2018/12/27
 */
@Slf4j
public class ConvertConfigurator extends PathNodeDataConsumerAdapter {

	private static final String BEAN_MAPPING = "beanMapping";

	private static final String TARGET_OBJECT = "targetObject";

	private static final int NODE_KEY_MIN_LENGTH = 3;

	private static final int NODE_KEY_MAX_LENGTH = 4;

	private static Pattern pattern = Pattern.compile("/product/[\\s\\S]*/convert_handler/[\\s\\S]*");

	@Resource
	private ConvertManager convertManager;

	@Override
	protected void handleNodeAdded(String path, String nodeValue) {
		Matcher matcher = pattern.matcher(path);
		if (matcher.matches()) {
			final String convertNodeName = StringUtils.substringAfterLast(path, "/");
			if (ConvertManager.contains(convertNodeName)) {
				log.error("格转配置节点:{} 已存在", convertNodeName);
				return;
			}
			update(path, nodeValue, convertNodeName);
		}
	}

	@Override
	protected void handleNodeUpdated(String path, String nodeValue) {
		Matcher matcher = pattern.matcher(path);
		if (matcher.matches()) {
			final String convertNodeName = StringUtils.substringAfterLast(path, "/");
			update(path, nodeValue, convertNodeName);
		}
	}

	@Override
	protected void handleNodeRemoved(String path, String nodeValue) {
		Matcher matcher = pattern.matcher(path);
		if (matcher.matches()) {
			convertManager.remove(StringUtils.substringAfterLast(path, "/"));
		}
	}

	private void update(String path, String nodeValue, String convertNodeName) {
		if (checkNode(path, nodeValue)) {
			final ConvertZkNode convertZkNode = JSON.toJavaObject(JSON.parseObject(nodeValue), ConvertZkNode.class);
			try {
				convertManager.add(convertNodeName, convertZkNode);
			} catch (ClassNotFoundException e) {
				log.debug("格转配置{}初始化异常", path, e);
			}
		}
	}

	/**
	 * 节点检查
	 *
	 * @param path
	 * @param nodeValue
	 * @return
	 */
	private boolean checkNode(String path, String nodeValue) {
		if (StringUtils.isAnyBlank(path, nodeValue)) {
			log.warn("格转zk配置为空");
			return false;
		}
		try {
			final JSONObject jsonObject = Optional.ofNullable(JSON.parseObject(nodeValue)).orElse(new JSONObject());
			int lengthSplit = ArrayUtils.getLength(StringUtils.split(StringUtils.substringAfterLast(path, "/"), "."));
			if (lengthSplit > NODE_KEY_MAX_LENGTH || lengthSplit < NODE_KEY_MIN_LENGTH) {
				log.error("节点:{}名称格式不符合规范", path);
				return false;
			}

			if (!jsonObject.containsKey(BEAN_MAPPING) || !jsonObject.containsKey(TARGET_OBJECT)) {
				log.error("节点:{}缺少{}或{}!", path, BEAN_MAPPING, TARGET_OBJECT);
				return false;
			}
		} catch (Exception e) {
			log.error("节点:{}反序列化发生异常", path, e);
			return false;
		}
		return true;
	}

}
